<?php
require_once __DIR__ . "/../Commons/logger.php";
require_once __DIR__ . "/../Commons/session.php";

/*
* Manage application packages.
*
* @method array GetPackages()
* @method boolean CreatePackage($version)
* @method boolean DeployPackage($package)
* @method void ExecuteScripts($scriptPath)
* @method void PackageScripts($scriptsFolder)
*/
class PackageManager
{	
	/*
	* @property string $RootPackages The root of packages repository
	*/
	private $RootPackages = null;
	
	/*
	* @property string $RootSite The root of the web site
	*/
	private $RootSite = null;
	
	/*
	* @property string $PackagePrefix The package prefix
	*/
	private $PackagePrefix = null;
	
	/*
	* @property FileSystemHelpers $FileSystemHelpers The file component manager
	*/
	private $FileSystemHelpers = null;
	
	/*
	* The default constructor
	*/
	public function __construct()
	{
		$this->RootPackages = __Dir__ . "/../../../BonoHome-Packages/";
		$this->FileSystemHelpers = new FileSystemHelpers();
		$this->PackagePrefix = "package-v";
		$this->RootSite = __Dir__ . "/../../../BonoHome";
	}

	/* 
	* Get all packages
	*
	* @return array The packages list
	*/
	public function GetPackages()
	{
		$result = null;
		try
		{
			Logger::Info("PackageManager - GetPackages all packages");
			$dirs = array();
			$files = array();
			$handle = opendir($this->RootPackages);
			while (false !== ($file = readdir($handle))) 
			{
				if ($file != "." && $file != "..")
				{
					$files[] = $file;
				}
			}
			
			//Ignore hidden files
			$files = preg_grep('/^([^.])/', $files);
			
			foreach($files as $val)
			{
				// If directory then dive deeper, else add file to directory key
				if(is_dir($this->RootPackages . '/' . $val))
				{
					array_push($dirs, $val);
				}
			}
			
			$result = $dirs;
		}
		catch (Exception $ex) 
		{
			Logger::Error($ex->getMessage());
		}
		
		return $result;
	}
	
	/*
	* Create a package
	*
	* @param string $version The package version
	*
	* @return boolean True if the package has been created
	*/
	public function CreatePackage($version)
	{
		Logger::Info("CreatePackage $version");
		
		$result = null;
		
		// compute the name
		$name = $this->PackagePrefix . $version;
		
		//Create all folders
		if(!file_exists($this->RootPackages))
		{
			mkdir($this->RootPackages);
		}
		$packageFolder = $this->RootPackages . $name;
		$scriptsFolder = $packageFolder . "/scripts";
		$sourcesFolder = $packageFolder . "/sources";
		if(!file_exists($packageFolder))
		{
			mkdir($packageFolder);
		}
		if(!file_exists($scriptsFolder))
		{
			mkdir($scriptsFolder);
		}
		if(!file_exists($sourcesFolder))
		{
			mkdir($sourcesFolder);
		}
		
		//Copy all scripts
		$result = $this->PackageScripts($scriptsFolder);
		
		//Copy sources
		$this->FileSystemHelpers->Copy($this->RootSite, $sourcesFolder);
		
		return true;
	}
	
	/*
	* Deploy a package
	*
	* @param string $package The package
	*
	* @result True if the package has been deployed
	*/
	public function DeployPackage($package)
	{
		//Delete current web site
		$fileSystemHelpers = new FileSystemHelpers();
		$fileSystemHelpers->Delete($this->RootSite);
		
		//Copy sources from package
		$fileSystemHelpers = new FileSystemHelpers();
		$result = $fileSystemHelpers->Copy(__Dir__ . "/../../../BonoHome-Packages/" . $package, $this->RootSite);
		
		//Execute scripts from packages
		$packageFolder = $this->RootPackages . $package;
		$scriptsFolder = $packageFolder . "/scripts";
		$files = array();
		$handle = opendir($this->scriptsFolder);
		while (false !== ($file = readdir($handle))) 
		{
			if ($file != "." && $file != ".." )
			{
				$files[] = $file;
			}
		}
		$files = preg_grep('/^([^.])/', $files);
		foreach($files as $val)
		{
			$this->ExecuteScripts($val);
		}

		return $result;
	}
	
	/*
	* Execute script
	*
	* @param string $scriptPath The script path to execute
	*/
	private function ExecuteScripts($scriptPath)
	{
		$session = Session::Singleton();
		$session->Open();
		// Select the current database
		$db_selected = mysql_select_db("bonohome");
		if (!$db_selected) 
		{
			Logger::Error("Unable to select database bonohome" . mysql_error());
		}
		$sql = file_get_contents($scriptPath);
		Logger::Debug("Exevute SQL script  : " . $sql);
		if (mysql_query($sql)) 
		{
			Logger::Info("Script was successfully executed");
		} 
		else 
		{
			Logger::Error("Script execution failed : " . mysql_error());
		}
		
		$session->Close();
	}
	
	/*
	* Copy all script to deploy
	*
	* @param string $scriptsFolder The script folder
	*/
	private function PackageScripts($scriptsFolder)
	{
		Logger::Info("PackageScripts -> Copy all scripts in $scriptsFolder");
		$parameters = Parameters::Singleton();
		$dirPath = $parameters::$Keys["TempPath"];
		$scripts = array();
		if ($handle = opendir($dirPath)) 
		{
			while (false !== ($entry = readdir($handle))) 
			{
				$extension = pathinfo($entry, PATHINFO_EXTENSION);
				if ($entry != "." && $entry != ".." && $extension == "sql") 
				{
					array_push($scripts, $entry);
				}
			}
			closedir($handle);
		}
		foreach($scripts as $script)
		{
			Logger::Info("PackageScripts -> copy script $script");
			$result = copy($dirPath . "/" . $script, $scriptsFolder . "/" . $script);
			
			if($result)
			{
				unlink($dirPath . "/" . $script);
			}
			
			Logger::Info("PackageScripts -> copy $script => $result");
		}
	}
}
?>